package com.ruoyi.web.controller.backstage;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ruoyi.common.core.domain.entity.SysShortUrl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.HrWebServiceUtil;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ShotUrlUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.dao.UserInfoDao;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static com.ruoyi.common.utils.TencentEmailUtils.tencentEmailNum;
import static com.ruoyi.common.utils.TencentEmailUtils.tencentEmailSsoIn;
import static com.ruoyi.framework.datasource.DynamicDataSourceContextHolder.log;

/**
 * 用户单点登录配置Controller
 * 
 * @author tjgc
 * @date 2020-12-21
 */
@RestController
@RequestMapping("/system/ssoConfig")
public class SysSsoConfigVoController extends BaseController
{
    @Autowired
    private ISysSsoConfigVoService sysSsoConfigVOService;

    @Resource
    private TokenService tokenService;

    @Resource
    private IWorkItemPendService iWorkItemPendService;

    @Resource
    private ISysSsoInfoService sysSsoInfoService;

    @Resource
    private IUserInfoEmailService iUserInfoEmailService;

    @Resource
    private UserInfoDao userInfoDao;

    @Resource
    private ISysShortUrlService iSysShortUrlService;

    @Resource
    private ISysSystemListService sysSystemListService;

    @Value("${interfaceAddress.hrWebServiceUrl}")
    public String hrWebServiceUrl;

    @Value("${interfaceAddress.portalAddress}")
    public String portalAddress;

    @Resource
    public IUserInfoIntegService iUserInfoIntegService;

    /**
     * 查询用户单点登录配置列表
     */
    @PreAuthorize("@ss.hasPermi('system:ssoConfig:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysSsoConfigVo sysSsoConfigVO)
    {
        startPage();
        List<SysSsoConfigVo> list = sysSsoConfigVOService.selectSysSsoConfigVOList(sysSsoConfigVO);
        return getDataTable(list);
    }
    @GetMapping("/allList")
    public TableDataInfo allList(SysSsoConfigVo sysSsoConfigVO)
    {
        long startLong = System.currentTimeMillis();
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser user = loginUser.getUser();
        String userNo = user.getUserNo();
        String phoneNumber = user.getPhonenumber();
        String userId = user.getUserId();
        Long id = user.getId();
        log.info("查询登陆人工号： {} , 手机号： {}, id:{}",userNo,phoneNumber,id);
        long mysqlStartLong = System.currentTimeMillis();
        List<String> userAuths = sysSsoConfigVOService.selectAuthSystemList(userNo);
        List<String> phoneAuths = sysSsoConfigVOService.selectAuthSystemListByPhone(phoneNumber);
        userAuths.addAll(phoneAuths);
        long mysqlEndLong = System.currentTimeMillis();
        log.info("数据库查询可单点登陆系统列表耗时： {}", (mysqlEndLong - mysqlStartLong));
        long viewStartLong = System.currentTimeMillis();
        try {
            List<String> authsInfo = userInfoDao.getAuthUserInfo(userNo);
            userAuths.addAll(authsInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
        long viewEndLong = System.currentTimeMillis();
        log.info("视图查询可单点登陆系统列表耗时： {}", (viewEndLong - viewStartLong));
        long sysStartLong = System.currentTimeMillis();
        List<String> sysAuthsInfo = iUserInfoIntegService.selectSysNameList(id.toString());
        if (sysAuthsInfo!=null&&sysAuthsInfo.size()>0){
            userAuths.addAll(sysAuthsInfo);
        }
        long sysEndLong = System.currentTimeMillis();
        log.info("后台用户查询可登陆系统列表耗时： {}", (sysEndLong - sysStartLong));
        if (userAuths.size() > 0) {
            sysSsoConfigVO.setAuths(userAuths);
        }

        log.info("工号为 {} 可以登录的系统有： {}",userNo,sysSsoConfigVO.getAuths());
        startPage();
        Map<String, SysSystemList> stringSysSystemListMap = sysSystemListService.selectSysSystemMap();
        List<SysSsoConfigVo> list = sysSsoConfigVOService.selectAuthSysSsoConfigVOList(sysSsoConfigVO);
        for (int i = 0; i < list.size(); i++) {
            SysSsoConfigVo sysSsoConfigVo = list.get(i);
            int pendCount = getPendCount(sysSsoConfigVo, userNo);
            sysSsoConfigVo.setPendCount(pendCount);
            SysSystemList sysSystemList = stringSysSystemListMap.get(sysSsoConfigVo.getSystemName());
            if (sysSystemList!=null){
                String sysName = sysSystemList.getSysName();
                sysSsoConfigVo.setSystemNameCn(sysName);
            }
        }

        long endLong = System.currentTimeMillis();
        log.info("查询可单点登陆系统列表耗时： {}", (endLong - startLong));
        return getDataTable(list);
    }

    @GetMapping("/ssoConfigList")
    public TableDataInfo ssoConfigList(SysSsoConfigVo sysSsoConfigVO)
    {
        startPage();
        List<SysSsoConfigVo> list = sysSsoConfigVOService.selectSysSsoConfigList(sysSsoConfigVO);
        return getDataTable(list);
    }


    /**
     * 导出用户单点登录配置列表
     */
    @PreAuthorize("@ss.hasPermi('system:ssoConfig:export')")
    @Log(title = "用户单点登录配置", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(SysSsoConfigVo sysSsoConfigVO)
    {
        List<SysSsoConfigVo> list = sysSsoConfigVOService.selectSysSsoConfigVOList(sysSsoConfigVO);
        ExcelUtil<SysSsoConfigVo> util = new ExcelUtil<SysSsoConfigVo>(SysSsoConfigVo.class);
        return util.exportExcel(list, "ssoConfig");
    }

    /**
     * 获取用户单点登录配置详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:ssoConfig:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(sysSsoConfigVOService.selectSysSsoConfigVOById(id));
    }

    /**
     * 新增用户单点登录配置
     */
    @PreAuthorize("@ss.hasPermi('system:ssoConfig:add')")
    @Log(title = "用户单点登录配置", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysSsoConfigVo sysSsoConfigVO)
    {
        return toAjax(sysSsoConfigVOService.insertSysSsoConfigVO(sysSsoConfigVO));
    }

    /**
     * 修改用户单点登录配置
     */
    @PreAuthorize("@ss.hasPermi('system:ssoConfig:edit')")
    @Log(title = "用户单点登录配置", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysSsoConfigVo sysSsoConfigVO)
    {
        return toAjax(sysSsoConfigVOService.updateSysSsoConfigVO(sysSsoConfigVO));
    }

    /**
     * 删除用户单点登录配置
     */
    @PreAuthorize("@ss.hasPermi('system:ssoConfig:remove')")
    @Log(title = "用户单点登录配置", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(sysSsoConfigVOService.deleteSysSsoConfigVOByIds(ids));
    }


    /**
     * 用户单点登录状态修改
     */
    @PreAuthorize("@ss.hasPermi('system:ssoConfig:edit')")
    @Log(title = "用户单点登录配置", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysSsoConfigVo SysSsoConfigVO)
    {
        logger.info("参数： {}",SysSsoConfigVO.toString());
        return toAjax(sysSsoConfigVOService.updateSysSsoConfigStatus(SysSsoConfigVO));
    }


    /**
     * 用户单点登录状态修改
     */
    @GetMapping ("/getSsoUrl")
    public AjaxResult getSsoUrl(Long id, HttpServletRequest request) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        String userNo = loginUser.getUser().getUserNo();
        SysSsoConfigVo sysSsoConfigVo = sysSsoConfigVOService.selectSysSsoConfigVOById(id);
        if (sysSsoConfigVo == null) {
            return AjaxResult.error("请联系管理员,设置此系统跳转");
        }
        String portalToken = tokenService.getToken(ServletUtils.getRequest());
        String ssoType = sysSsoConfigVo.getSsoType();
        String openWay = sysSsoConfigVo.getOpenWay();
        String systemName = sysSsoConfigVo.getSystemName();
        String ssoUrl;
        Map<String, String> urlMap = new HashMap<>(2);
        //单点登陆类型(1=token登陆,2=token通用,3=模拟登陆,4=链接跳转)
        switch (ssoType){
            case "1":
                ssoUrl = getNotTypicalTokenUrl(systemName, sysSsoConfigVo, userNo,portalToken);
                break;
            case "2":
                ssoUrl = sysSsoConfigVo.getSsoUrl() + "?token=" + portalToken;
                break;
            case "3":
                ssoUrl=getSimulateUrl(systemName, sysSsoConfigVo, userNo);
                break;
            case "4":
                ssoUrl = sysSsoConfigVo.getSsoUrl();
                break;
            default:
                ssoUrl=null;
        }
        log.info("用户 ：{} ,登陆的系统是 <{}> 拼接的单点登录地址是： {}",userNo,systemName,ssoUrl);
        if (ssoUrl==null){
            return AjaxResult.error("未设置账号信息");
        }else {

            if ("1".equals(openWay)){
                String ssoShotUrl = ShotUrlUtils.generatorShortUrl(ssoUrl);
                SysShortUrl sysShortUrl = new SysShortUrl();
                sysShortUrl.setShortUrl(ssoShotUrl);
                sysShortUrl.setSrcUrl(ssoUrl);
                sysShortUrl.setCreateBy(userNo);
                iSysShortUrlService.insertSysShortUrl(sysShortUrl);
                urlMap.put("URL", portalAddress+"/link/"+ssoShotUrl);
            }else {
                urlMap.put("URL", ssoUrl);
            }
            urlMap.put("openWay",openWay);
            return AjaxResult.success("成功",urlMap);
        }

    }

    /**
     * 暂时无用
     * @param id
     * @return
     */
    @GetMapping ("/getSsoPendCount")
    public AjaxResult getSsoPendCount(Long id) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        String userNo = loginUser.getUser().getUserNo();
        SysSsoConfigVo sysSsoConfigVo = sysSsoConfigVOService.selectSysSsoConfigVOById(id);
        if (sysSsoConfigVo == null) {
            return AjaxResult.error("无此系统");
        }
        int pendCount = getPendCount(sysSsoConfigVo, userNo);
        return AjaxResult.success("成功",pendCount);
    }

    private String getNotTypicalTokenUrl(String systemName,SysSsoConfigVo sysSsoConfigVo,String userNo,String portalToken){
        String ssoUrl;
        if ("HR".equals(systemName)) {
            String hrToken = HrWebServiceUtil.getHrToken(userNo, 0,hrWebServiceUrl);
            ssoUrl = sysSsoConfigVo.getSsoUrl() + "?Token=" + hrToken;
        } else if ("email".equals(systemName)) {
            UserInfoEmail userInfoEmail = iUserInfoEmailService.selectUserInfoEmailByUserNo(userNo);
            ssoUrl = userInfoEmail == null ? null : tencentEmailSsoIn(userInfoEmail.getEmail());
        } else if ("BPM".equals(systemName)) {
            ssoUrl = sysSsoConfigVo.getSsoUrl() + "?code=" + userNo + "&flag=1";
        } else if("EC".equals(systemName)){
            ssoUrl = sysSsoConfigVo.getSsoUrl()+portalToken;
        }else if ("FR".equals(systemName)){
            ssoUrl = sysSsoConfigVo.getSsoUrl() + "?fr_username="+userNo;
        }else {
            ssoUrl = null;
        }
        return ssoUrl;
    }

    private String getSimulateUrl(String systemName,SysSsoConfigVo sysSsoConfigVo,String userNo){
        SysSsoInfo sysSsoInfo = sysSsoInfoService.selectSysSsoInfoByOne(systemName, userNo);
        if (sysSsoInfo==null){
            return null;
        }
        String userName = sysSsoInfo.getUserName();
        String password = sysSsoInfo.getPassword();
        String ssoUrl = sysSsoConfigVo.getSsoUrl();
        StringBuffer stringBuffer = new StringBuffer();
        StringBuffer allUrl = stringBuffer.append(ssoUrl)
                .append("?").append(sysSsoConfigVo.getUsernameStr())
                .append("=").append(userName).append("&")
                .append(sysSsoConfigVo.getPasswordStr())
                .append("=").append(password);
        log.info("allUrl :  {}",allUrl);
        log.info("url地址 ： {}",ssoUrl);
        return allUrl.toString();
    }

    /**
     * 获取待办数量
     * @param sysSsoConfigVo
     * @param userNo
     * @return
     */
    private Integer getPendCount(SysSsoConfigVo sysSsoConfigVo,String userNo ){
        String systemName = sysSsoConfigVo.getSystemName();
        Integer count=0;
        switch (systemName){
            case "OA":
                count = iWorkItemPendService.selectWorkItemPendCountBySystem("OA", userNo);
                break;
            case "HR":
                count = iWorkItemPendService.selectWorkItemPendCountBySystem("HR", userNo);
                break;
            case "EC":
                count = iWorkItemPendService.selectWorkItemPendCountBySystem("EC", userNo);
                break;
            case "BPM":
                List<String> systemNames = new ArrayList<>(2);
                systemNames.add("EC");
                systemNames.add("Portal");
                count = iWorkItemPendService.selectWorkItemPendCountBpm(systemNames, userNo);
                break;
            case "email":
                try {
                    UserInfoEmail userInfoEmail = iUserInfoEmailService.selectUserInfoEmailByUserNo(userNo);
                    count = userInfoEmail == null ? 0 :tencentEmailNum(userInfoEmail.getEmail());
                } catch (Exception e) {
                    count = 0;
                    e.printStackTrace();
                }
                break;
            default:
                count=0;
        }
        return count;
    }
    
    /**
     * 获取服务大厅完整链接
     */
    @Log(title = "获取服务大厅完整链接", businessType = BusinessType.INSERT)
    @PostMapping("/getServiceRoomLink")
    public AjaxResult getServiceRoomLink(@RequestBody SysServiceRoom sysServiceRoom)
    {
    	 LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String userNo = loginUser.getUser().getUserNo();
         String portalToken = tokenService.getToken(ServletUtils.getRequest());
        String url = "";
 		Map<String, String> urlMap = new HashMap<>(2);
 		if(StringUtils.isNotBlank(sysServiceRoom.getType())) {
 			
 			if("hr_workflow_link".equals(sysServiceRoom.getType())) {
 				SysSsoConfigVo sysSsoConfigVo = sysSsoConfigVOService.selectSysSsoConfigVOByName("HR");
 				String hrToken = HrWebServiceUtil.getHrToken(userNo, 0,hrWebServiceUrl);
 				url = sysSsoConfigVo.getSsoUrl() + "?Token=" + hrToken;
 				
 				if (null!=sysSsoConfigVo && "1".equals(sysSsoConfigVo.getOpenWay())){
 		            String ssoUrl = url.toString();
 		            String ssoShotUrl = ShotUrlUtils.generatorShortUrl(ssoUrl);
 		            SysShortUrl sysShortUrl = new SysShortUrl();
 		            sysShortUrl.setCreateBy(userNo);
 		            sysShortUrl.setShortUrl(ssoShotUrl);
 		            sysShortUrl.setSrcUrl(ssoUrl);
 		            iSysShortUrlService.insertSysShortUrl(sysShortUrl);
 		            urlMap.put("URL", portalAddress+"/link/"+ssoShotUrl);
 		        }else {
 		            urlMap.put("URL", url.toString());
 		        }
 				
 		        if(null!=sysSsoConfigVo){
 		            urlMap.put("openWay",sysSsoConfigVo.getOpenWay());
 		        }else{
 		        	urlMap.put("openWay", "0");
	        	}
 			}
 			
 			if("ec_link".equals(sysServiceRoom.getType())) {
 				SysSsoConfigVo sysSsoConfigVo = sysSsoConfigVOService.selectSysSsoConfigVOByName("EC");
 				url = sysSsoConfigVo.getSsoUrl()+portalToken;
 				
 				if (null!=sysSsoConfigVo && "1".equals(sysSsoConfigVo.getOpenWay())){
 		            String ssoUrl = url.toString();
 		            String ssoShotUrl = ShotUrlUtils.generatorShortUrl(ssoUrl);
 		            SysShortUrl sysShortUrl = new SysShortUrl();
 		            sysShortUrl.setCreateBy(userNo);
 		            sysShortUrl.setShortUrl(ssoShotUrl);
 		            sysShortUrl.setSrcUrl(ssoUrl);
 		            iSysShortUrlService.insertSysShortUrl(sysShortUrl);
 		            urlMap.put("URL", portalAddress+"/link/"+ssoShotUrl);
 		        }else {
 		            urlMap.put("URL", url.toString());
 		        }
 				
 		        if(null!=sysSsoConfigVo){
 		            urlMap.put("openWay",sysSsoConfigVo.getOpenWay());
 		        }else{
 		        	urlMap.put("openWay", "0");
	        	}
 			}
 			
 			if("oa_workflow_link".equals(sysServiceRoom.getType())) {
 				SysSsoConfigVo sysSsoConfigVo = sysSsoConfigVOService.selectSysSsoConfigVOByName("OA");
 				String systemToken = tokenService.getToken(ServletUtils.getRequest());
 				url =  sysSsoConfigVo.getSsoUrl()+"?token="+systemToken+
                        "&toLink="+ URLEncoder.encode(sysServiceRoom.getLink());
 				if (null!=sysSsoConfigVo && "1".equals(sysSsoConfigVo.getOpenWay())){
 		            String ssoUrl = url.toString();
 		            String ssoShotUrl = ShotUrlUtils.generatorShortUrl(ssoUrl);
 		            SysShortUrl sysShortUrl = new SysShortUrl();
 		            sysShortUrl.setCreateBy(userNo);
 		            sysShortUrl.setShortUrl(ssoShotUrl);
 		            sysShortUrl.setSrcUrl(ssoUrl);
 		            iSysShortUrlService.insertSysShortUrl(sysShortUrl);
 		            urlMap.put("URL", portalAddress+"/link/"+ssoShotUrl);
 		        }else {
 		            urlMap.put("URL", url.toString());
 		        }
 				
 		        if(null!=sysSsoConfigVo){
 		            urlMap.put("openWay",sysSsoConfigVo.getOpenWay());
 		        }else{
 		        	urlMap.put("openWay", "0");
	        	}
 			}
 		}
 		
        return AjaxResult.success(urlMap);
    }

}
